#include "list.h"

/**
 * @brief 初始化钩子节点
 *
 * @param[in] pxItem : 指向节点的指针
 *
 * @return  void.
 *
 * */
void vListInitialiseItem(ListItem_t * const pxItem)
{
	/* 初始化的时候只需要将 pvContainer 置空, 表示未插入到任何链表当中 */
	pxItem->pvContainer = NULL;
}

/**
 * @brief 链表初始化
 *
 * @param[in] pxList : 指向链表的指针
 *
 * @return  void.
 *
 * */
void vListInitialise(List_t * const pxList)
{
	/* 将链表索引指针指向最后一个节点 : 精简节点类型转换为节点类型*/
	pxList->pxIndex = (ListItem_t *)(&(pxList->xListEnd));
	
	/* 将链表最后一个节点的辅助排序的值设置为最大, 确保该节点就是链表的最后节点 */
	pxList->xListEnd.xItemValue = portMAX_DELAY;
	
	/* 将最后一个节点的 pxNext 和 pxPrevious 指针均指向节点自身, 表示链表为空*/
	pxList->xListEnd.pxNext     = (ListItem_t *)&(pxList->xListEnd);
	pxList->xListEnd.pxPrevious = (ListItem_t *)&(pxList->xListEnd);
	
	/* 初始化链表节点计数器的值为0, 表示链表为空 */
	pxList->uxNumberOfItems = (UBaseType_t) 0U;
}

/**
 * @brief 链表尾部插入节点
 *
 * @param[in] pxList        : 指向链表的指针
 * @param[in] pxNewListItem : 被插入的节点
 *
 * @return  void.
 *
 * */
void vListInsertEnd(List_t * const pxList, ListItem_t * const pxNewListItem)
{
	ListItem_t * const pxIndex = pxList->pxIndex;
	
	/* 待插入节点插入到 pxIndex 指向的节点前 */
	pxNewListItem->pxNext       = pxIndex;
	pxNewListItem->pxPrevious   = pxIndex->pxPrevious;
	pxIndex->pxPrevious->pxNext = pxNewListItem;
	pxIndex->pxPrevious = pxNewListItem;
	
	/* 记住该节点所在的链表 */
	pxNewListItem->pvContainer = (void *)pxList;
	
	/* 头节点中计数器++ */
	(pxList->uxNumberOfItems)++;
}

/**
 * @brief 按照升序将节点插入到链表中
 *
 * @param[in] pxList        : 指向链表的指针
 * @param[in] pxNewListItem : 被插入的节点
 *
 * @return  void.
 *
 * */
void vListInsert(List_t * const pxList, ListItem_t * const pxNewListItem)
{
	/* 迭代器: 待插入节点插入迭代器指向的节点之后 */
	ListItem_t *pxIterator = NULL;

	/* 获取待插入节点的排序辅助值 */
	const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;

	/* 若待插入节点的辅助值 == portMAX_DELAY, 则 iterator 指向 end 节点的前一个位置 */
	/* if 属于优化代码, 去掉的话, 极端条件会走一个 O(n) 复杂度的循环, */
	if( xValueOfInsertion == portMAX_DELAY )
	{
		pxIterator = pxList->xListEnd.pxPrevious;
	}
	
	/* 循环查找查找插入位置 */
	else
	{
		for( pxIterator = (ListItem_t *) & (pxList->xListEnd);
		     pxIterator->pxNext->xItemValue <= xValueOfInsertion;
				 pxIterator = pxIterator->pxNext )
		{
			
		}
	}
	
	/* 根据升序排列, 将节点插入 */
	pxNewListItem->pxNext          = pxIterator->pxNext;
	pxIterator->pxNext->pxPrevious = pxNewListItem;
	pxNewListItem->pxPrevious      = pxIterator;
	pxIterator->pxNext             = pxNewListItem;
	
	/* 记住该节点所在的链表 */
	pxNewListItem->pvContainer     = (void *) pxList;
	
	/* 链表节点计数器 */
	(pxList->uxNumberOfItems)++;
}


/**
 * @brief 从链表中删除节点
 *
 * @param[in] pxItemToRemove : 指向被删除节点的指针
 *
 * @return  void.
 *
 * */
UBaseType_t uxListRemove(ListItem_t * const pxItemToRemove)
{
	/* 获取节点所在的链表 */
	List_t * const pxList = (List_t *) pxItemToRemove->pvContainer;
	
	/* 将指定的节点从链表删除 */
	pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
	pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;
	
	/* 调整链表节点的索引指针 */
	if(pxList->pxIndex == pxItemToRemove)
	{
		pxList->pxIndex = pxItemToRemove->pxPrevious;
	}
	
	/* 初始化该节点所在的链表为空, 表示该节点还没有插入任何链表 */
	pxItemToRemove->pvContainer = NULL;
	
	/* 链表节点计数器-- */
	(pxList->uxNumberOfItems)--;
	
	/* 返回链表中剩余节点的个数 */
	return pxList->uxNumberOfItems;
}
